/**
 * HTTP请求封装
 * 基于fetch API封装，支持拦截器、错误处理、Token管理等
 */

import AsyncStorage from '@react-native-async-storage/async-storage';
import { API_CONFIG, ERROR_MESSAGES, STORAGE_KEYS } from './config';

class HttpRequest {
  constructor() {
    this.baseURL = API_CONFIG.BASE_URL;
    this.timeout = API_CONFIG.TIMEOUT;
    this.defaultHeaders = API_CONFIG.DEFAULT_HEADERS;

    // 请求拦截器
    this.requestInterceptors = [];
    // 响应拦截器
    this.responseInterceptors = [];

    // 添加默认拦截器
    this.addDefaultInterceptors();
  }

  /**
   * 添加默认拦截器
   */
  addDefaultInterceptors() {
    // 请求拦截器 - 添加Token
    this.addRequestInterceptor(async config => {
      // 从本地存储读取token（用户登录后的access_token）
      const token = await AsyncStorage.getItem('user_token');
      if (token) {
        // 确保headers对象存在
        config.headers = config.headers || {};
        // 添加Authorization头，带 Bearer 前缀
        config.headers['Authorization'] = `Bearer ${token}`;
      }
      return config;
    });

    // 响应拦截器 - 处理Token过期
    this.addResponseInterceptor(
      response => response,
      async error => {
        if (error.status === API_CONFIG.STATUS_CODES.UNAUTHORIZED) {
          try {
            // 尝试刷新Token
            const refreshToken = await AsyncStorage.getItem(
              STORAGE_KEYS.REFRESH_TOKEN,
            );
            if (refreshToken) {
              const newToken = await this.refreshToken(refreshToken);
              if (newToken) {
                // 重新发送原请求
                return this.request(error.config);
              }
            }
          } catch {
            // Ignore refresh token errors
          }

          // 清除Token并跳转到登录页
          await this.clearTokens();
          // 这里可以添加跳转到登录页的逻辑
        }
        return Promise.reject(error);
      },
    );
  }

  /**
   * 添加请求拦截器
   */
  addRequestInterceptor(fulfilled, rejected) {
    this.requestInterceptors.push({ fulfilled, rejected });
  }

  /**
   * 添加响应拦截器
   */
  addResponseInterceptor(fulfilled, rejected) {
    this.responseInterceptors.push({ fulfilled, rejected });
  }

  /**
   * 执行请求拦截器
   */
  async executeRequestInterceptors(config) {
    let processedConfig = config;
    for (const interceptor of this.requestInterceptors) {
      try {
        if (interceptor.fulfilled) {
          processedConfig = await interceptor.fulfilled(processedConfig);
        }
      } catch (error) {
        if (interceptor.rejected) {
          return interceptor.rejected(error);
        }
        throw error;
      }
    }
    return processedConfig;
  }

  /**
   * 执行响应拦截器
   */
  async executeResponseInterceptors(response, isError = false) {
    let processedResponse = response;
    for (const interceptor of this.responseInterceptors) {
      const handler = isError ? interceptor.rejected : interceptor.fulfilled;
      if (handler) {
        processedResponse = await handler(processedResponse);
      }
    }
    return processedResponse;
  }

  /**
   * 刷新Token
   */
  async refreshToken(refreshToken) {
    try {
      const response = await fetch(
        `${this.baseURL}${API_CONFIG.ENDPOINTS.REFRESH_TOKEN}`,
        {
          method: 'POST',
          headers: this.defaultHeaders,
          body: JSON.stringify({ refreshToken }),
        },
      );

      if (response.ok) {
        const data = await response.json();
        await AsyncStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, data.accessToken);
        if (data.refreshToken) {
          await AsyncStorage.setItem(
            STORAGE_KEYS.REFRESH_TOKEN,
            data.refreshToken,
          );
        }
        return data.accessToken;
      }
    } catch {
      // Ignore token refresh errors
    }
    return null;
  }

  /**
   * 清除Token
   */
  async clearTokens() {
    try {
      await AsyncStorage.multiRemove([
        STORAGE_KEYS.ACCESS_TOKEN,
        STORAGE_KEYS.REFRESH_TOKEN,
        STORAGE_KEYS.USER_INFO,
      ]);
    } catch {
      // Ignore token clear errors
    }
  }

  /**
   * 构建完整URL
   */
  buildURL(url, params = {}) {
    let fullURL = url.startsWith('http') ? url : `${this.baseURL}${url}`;

    // 替换路径参数
    Object.keys(params).forEach(key => {
      fullURL = fullURL.replace(`:${key}`, params[key]);
    });

    return fullURL;
  }

  /**
   * 构建查询字符串
   */
  buildQueryString(params) {
    if (!params || Object.keys(params).length === 0) {
      return '';
    }

    const queryString = Object.keys(params)
      .filter(key => params[key] !== undefined && params[key] !== null)
      .map(
        key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`,
      )
      .join('&');

    return queryString ? `?${queryString}` : '';
  }

  /**
   * 处理响应
   */
  async handleResponse(response, config) {
    const contentType = response.headers.get('content-type');
    let data;

    try {
      if (contentType && contentType.includes('application/json')) {
        data = await response.json();
      } else {
        data = await response.text();
      }
    } catch {
      data = null;
    }

    const result = {
      data,
      status: response.status,
      statusText: response.statusText,
      headers: response.headers,
      config,
    };

    if (response.ok) {
      return this.executeResponseInterceptors(result);
    } else {
      const error = new Error(this.getErrorMessage(response.status));
      error.response = result;
      error.status = response.status;
      error.config = config;

      throw await this.executeResponseInterceptors(error, true);
    }
  }

  /**
   * 获取错误消息
   */
  getErrorMessage(status) {
    switch (status) {
      case API_CONFIG.STATUS_CODES.BAD_REQUEST:
        return ERROR_MESSAGES.BAD_REQUEST;
      case API_CONFIG.STATUS_CODES.UNAUTHORIZED:
        return ERROR_MESSAGES.UNAUTHORIZED;
      case API_CONFIG.STATUS_CODES.FORBIDDEN:
        return ERROR_MESSAGES.FORBIDDEN;
      case API_CONFIG.STATUS_CODES.NOT_FOUND:
        return ERROR_MESSAGES.NOT_FOUND;
      case API_CONFIG.STATUS_CODES.SERVER_ERROR:
        return ERROR_MESSAGES.SERVER_ERROR;
      default:
        return ERROR_MESSAGES.UNKNOWN_ERROR;
    }
  }

  /**
   * 创建超时Promise
   */
  createTimeoutPromise(timeout) {
    return new Promise((_, reject) => {
      setTimeout(() => {
        reject(new Error(ERROR_MESSAGES.TIMEOUT_ERROR));
      }, timeout);
    });
  }

  /**
   * 核心请求方法（带重试机制）
   */
  async request(config, retryCount = 0) {
    const maxRetries = config.maxRetries || 2; // 默认最多重试2次

    try {
      // 确保config有基本结构
      const safeConfig = {
        headers: {},
        ...config,
      };

      // 执行请求拦截器
      const processedConfig = await this.executeRequestInterceptors(safeConfig);

      // 构建URL
      const url = this.buildURL(
        processedConfig.url,
        processedConfig.pathParams,
      );
      const queryString = this.buildQueryString(processedConfig.params);
      const fullURL = `${url}${queryString}`;

      // 构建请求选项
      const fetchOptions = {
        method: processedConfig.method || 'GET',
        headers: {
          ...this.defaultHeaders,
          ...processedConfig.headers,
        },
      };

      // 添加请求体
      if (processedConfig.data) {
        if (
          processedConfig.headers &&
          processedConfig.headers['Content-Type'] === 'multipart/form-data'
        ) {
          // 文件上传，让浏览器自动设置Content-Type
          delete fetchOptions.headers['Content-Type'];
          fetchOptions.body = processedConfig.data;
        } else {
          fetchOptions.body = JSON.stringify(processedConfig.data);
        }
      }

      // 发送请求（带超时）
      const fetchPromise = fetch(fullURL, fetchOptions);
      const timeoutPromise = this.createTimeoutPromise(this.timeout);

      const response = await Promise.race([fetchPromise, timeoutPromise]);

      // 处理响应
      return await this.handleResponse(response, processedConfig);
    } catch (error) {
      // 超时错误 - 自动重试
      if (
        error.message === ERROR_MESSAGES.TIMEOUT_ERROR &&
        retryCount < maxRetries
      ) {
        // 等待一段时间后重试（指数退避）
        await new Promise(resolve =>
          setTimeout(resolve, 500 * (retryCount + 1)),
        );
        return this.request(config, retryCount + 1);
      }

      // 网络错误 - 可能也需要重试
      if (!error.response && retryCount < maxRetries) {
        await new Promise(resolve =>
          setTimeout(resolve, 500 * (retryCount + 1)),
        );
        return this.request(config, retryCount + 1);
      }

      // 其他错误或已达到最大重试次数
      if (error.message === ERROR_MESSAGES.TIMEOUT_ERROR) {
        throw error;
      } else if (!error.response) {
        const networkError = new Error(ERROR_MESSAGES.NETWORK_ERROR);
        networkError.config = config;
        throw networkError;
      }
      throw error;
    }
  }

  /**
   * GET请求
   */
  get(url, params = {}, config = {}) {
    return this.request({
      method: 'GET',
      url,
      params,
      ...config,
    });
  }

  /**
   * POST请求
   */
  post(url, data = {}, config = {}) {
    return this.request({
      method: 'POST',
      url,
      data,
      ...config,
    });
  }

  /**
   * PUT请求
   */
  put(url, data = {}, config = {}) {
    return this.request({
      method: 'PUT',
      url,
      data,
      ...config,
    });
  }

  /**
   * DELETE请求
   */
  delete(url, config = {}) {
    return this.request({
      method: 'DELETE',
      url,
      ...config,
    });
  }

  /**
   * PATCH请求
   */
  patch(url, data = {}, config = {}) {
    return this.request({
      method: 'PATCH',
      url,
      data,
      ...config,
    });
  }

  /**
   * 文件上传
   */
  upload(url, file, data = {}, onProgress = null) {
    const formData = new FormData();

    // 添加文件
    if (file) {
      formData.append('file', file);
    }

    // 添加其他数据
    Object.keys(data).forEach(key => {
      formData.append(key, data[key]);
    });

    return this.request({
      method: 'POST',
      url,
      data: formData,
      headers: {
        ...API_CONFIG.UPLOAD_HEADERS,
      },
      onProgress,
    });
  }
}

// 创建默认实例
const httpRequest = new HttpRequest();

export default httpRequest;
export { HttpRequest };
